﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Caifu.Clients;

namespace Caifu.WebAdmin.NetValues
{
	public partial class CheckNetValue : System.Web.UI.Page
	{
		protected int m_i;
		protected int m_ResultType;
		protected int p_Days;	// 成立天数；当该参数>0时，则表示需要显示的数据为成立天数小于该参数

		/// <summary>
		/// 报告日期
		/// </summary>
		protected DateTime ReportDate
		{
			get
			{
				return TradeDateUtil.GetNetDailyDate();
			}
		}

		protected void Page_Load(object sender, EventArgs e)
		{
			m_ResultType = Itfort.Web.RequestUtil.ToInt32("resulttype");
			p_Days = Itfort.Web.RequestUtil.ToInt32("days");

			if (p_Days > 0)
			{
				this.Repeater1.DataSource = this.GetAllCheckedEntries().Where(p => p.AccumulatedNetValueGrowthValue != p.UnitNetValueGrowthValue).ToList();
			}
			else
			{
				var dataSouce = this.GetAllCheckedEntries();
				this.Repeater1.DataSource = dataSouce;
			}
			this.DataBind();
		}

		protected DataTable GetCheckedResult()
		{
			var reportDate = ReportDate;

			var funds = FundClient.GetAllFunds();
			var netValuePres = NetValuePreClient.GetNetValuePres(reportDate);

			var netValuePreDict = netValuePres.ToDictionary(p => p.FundCode, p => p);

			// 出了净值，并且在基金表中也能找到对应基金
			var normalNetValuePreDict = netValuePres.Where(p => p.FundId != Guid.Empty).ToDictionary(p => p.FundId, p => p);
			// 出了净值，但是在基金表中未能找到对应基金
			var lessFundOfNetValuePres = netValuePres.Where(p => p.FundId == Guid.Empty).ToList();
			// 尚未出净值的基金
			var notExistNetValue_Funds = funds.Where(p => !normalNetValuePreDict.ContainsKey(p.Id)).ToList();

			var wrongNetValuePres = new List<NetValuePre>(); //错误净值
			var lessNavOfFunds = new List<Fund>(); //缺少净值的基金
			var bonusFunds = new List<Fund>(); //存在分红、拆分、折算。

			foreach (var fund in funds)
			{
				NetValuePre nvpre;
				//var existInNetValuePre = normalNetValuePreDict.TryGetValue(fund.Id, out nvpre);
				var existInNetValuePre = netValuePreDict.TryGetValue(fund.Code, out nvpre);

				if (fund.IsQDII)
				{

				}
				else if (fund.FundType == (int)FundType.ClosedEnd)
				{

				}
				else if (fund.FundType == (int)FundType.Innovative)
				{

				}
				else if (fund.FundType == (int)FundType.OpenEnd)
				{
					if (existInNetValuePre)
					{
						if (nvpre.CheckStatus < 0)
						{
							wrongNetValuePres.Add(nvpre);
						}
						else if (nvpre.CheckStatus < 2)
						{
							wrongNetValuePres.Add(nvpre);
						}

						//当单位净值与累计净值与前一交易日相比不同步增加时，即存在分红
					}
					else
					{
						lessNavOfFunds.Add(fund);
					}
				}
			}

			DataTable table = new DataTable();
			table.Columns.Add("FundCode");
			table.Columns.Add("FundName");
			table.Columns.Add("UnitNetValue");
			table.Columns.Add("AccumulatedNetValue");
			table.Columns.Add("UnitNetValue1");
			table.Columns.Add("AccumulatedNetValue1");
			table.Columns.Add("UnitNetValue2");
			table.Columns.Add("AccumulatedNetValue2");
			table.Columns.Add("UnitNetValue3");
			table.Columns.Add("AccumulatedNetValue3");
			table.Columns.Add("ReportDate");
			table.Columns.Add("Duration");

			foreach (var netValuePre in lessFundOfNetValuePres)
			{
				var row = table.NewRow();
				row["FundCode"] = netValuePre.FundCode;
				row["UnitNetValue"] = netValuePre.UnitNetValue;
				row["AccumulatedNetValue"] = netValuePre.AccumulatedNetValue;
				row["UnitNetValue1"] = netValuePre.UnitNetValue1;
				row["AccumulatedNetValue1"] = netValuePre.AccumulatedNetValue1;
				row["UnitNetValue2"] = netValuePre.UnitNetValue2;
				row["AccumulatedNetValue2"] = netValuePre.AccumulatedNetValue2;
				row["UnitNetValue3"] = netValuePre.UnitNetValue3;
				row["AccumulatedNetValue3"] = netValuePre.AccumulatedNetValue3;

				table.Rows.Add(row);
			}

			foreach (var netValuePre in wrongNetValuePres)
			{
				var row = table.NewRow();
				row["FundCode"] = netValuePre.FundCode;
				row["UnitNetValue"] = netValuePre.UnitNetValue;
				row["AccumulatedNetValue"] = netValuePre.AccumulatedNetValue;
				row["UnitNetValue1"] = netValuePre.UnitNetValue1;
				row["AccumulatedNetValue1"] = netValuePre.AccumulatedNetValue1;
				row["UnitNetValue2"] = netValuePre.UnitNetValue2;
				row["AccumulatedNetValue2"] = netValuePre.AccumulatedNetValue2;
				row["UnitNetValue3"] = netValuePre.UnitNetValue3;
				row["AccumulatedNetValue3"] = netValuePre.AccumulatedNetValue3;

				var fund = FundClient.GetFund(netValuePre.FundCode);
				row["FundName"] = fund.Name;
				var duration = reportDate - fund.Established.Value;
				row["Duration"] = duration.Days + "天";

				table.Rows.Add(row);
			}

			foreach (var item in lessNavOfFunds)
			{
				var row = table.NewRow();
				row["FundCode"] = item.Code;
				row["FundName"] = item.Name;

				var duration = reportDate - item.Established.Value;
				row["Duration"] = duration.Days + "天";

				table.Rows.Add(row);
			}

			//var fundDict = funds.ToDictionary(p => p.Id, p => p);

			//var rows_Normal = new List<DataRow>(); // 能采集到净值，也能找到对应的基金
			//var rows_NoFund = new List<DataRow>(); // 能采集到净值，但找不到对应的基金
			//var rows_Error = new List<DataRow>(); // 能采集到净值，但是净值核对不上
			//var rows_NoNav = new List<DataRow>(); // 没有采集到净值的基金记录

			//foreach (var netValuePre in netValuePres)
			//{
			//    // 已出净值，但需要人工核对的状态
			//    if (netValuePre.CheckStatus < 2)
			//    {
			//        var row = table.NewRow();
			//        row["FundCode"] = netValuePre.FundCode;

			//        row["UnitNetValue"] = netValuePre.UnitNetValue;
			//        row["AccumulatedNetValue"] = netValuePre.AccumulatedNetValue;
			//        row["UnitNetValue1"] = netValuePre.UnitNetValue1;
			//        row["AccumulatedNetValue1"] = netValuePre.AccumulatedNetValue1;
			//        row["UnitNetValue2"] = netValuePre.UnitNetValue2;
			//        row["AccumulatedNetValue2"] = netValuePre.AccumulatedNetValue2;
			//        row["UnitNetValue3"] = netValuePre.UnitNetValue3;
			//        row["AccumulatedNetValue3"] = netValuePre.AccumulatedNetValue3;

			//        if (netValuePre.FundId != Guid.Empty)
			//        {
			//            Fund fundInfo;
			//            if (fundDict.TryGetValue(netValuePre.FundId, out fundInfo))
			//            {
			//                row["FundName"] = fundInfo.Name;
			//            }

			//            if (netValuePre.CheckStatus <= 0)
			//            {// 怀疑有错的净值
			//                rows_Error.Add(row);
			//            }
			//            else
			//            {
			//                rows_Normal.Add(row);
			//            }
			//        }
			//        else
			//        {// 无法对应到基金的记录
			//            rows_NoFund.Add(row);
			//        }
			//    }
			//}

			//foreach (var item in notExistNetValue_Funds)
			//{
			//    var row = table.NewRow();
			//    row["FundCode"] = item.FundCode;
			//    row["FundName"] = item.Name;

			//    if (item.FundType != (int)FundType.ClosedEnd)
			//    {
			//        if (item.FundType != (int)FundType.Currency && DateTime.Today - item.Established > new TimeSpan(30, 0, 0, 0))
			//        {
			//            rows_NoNav.Add(row);
			//        }
			//    }
			//    else if (reportDate.DayOfWeek == DayOfWeek.Friday)
			//    {
			//        rows_NoNav.Add(row);
			//    }
			//}

			//rows_NoFund.ForEach(p => table.Rows.Add(p));
			//rows_Error.ForEach(p => table.Rows.Add(p));
			//rows_Normal.ForEach(p => table.Rows.Add(p));
			//rows_NoNav.ForEach(p => table.Rows.Add(p));

			return table;
		}

		protected List<CheckedEntry> GetAllCheckedEntries()
		{
			var reportDate = ReportDate;

			var funds = FundClient.GetAllFunds();
			var fundDict = funds.ToDictionary(p => p.Code, p => p);
			var netValuePres = NetValuePreClient.GetNetValuePres(reportDate);
			var netValuePreDict = netValuePres.ToDictionary(p => p.FundCode, p => p);
			var t_1 = TradeDateUtil.GetPreviousTradeDate(reportDate);
			var t_1NetValues = NetValueClient.GetNetValues(t_1);
			var t_1NetValueDict = t_1NetValues.ToDictionary(p => p.FundId, p => p);

			List<CheckedEntry> dataSource = new List<CheckedEntry>();
			foreach (var fund in funds)
			{
				NetValuePre netValuePre;
				if (!netValuePreDict.TryGetValue(fund.Code, out netValuePre))
				{
					netValuePre = null;
				}
				NetValue t_1NetValue;
				if (!t_1NetValueDict.TryGetValue(fund.Id, out t_1NetValue))
				{
					t_1NetValue = null;
				}
				CheckedEntry dataEntry = new CheckedEntry(reportDate, fund, netValuePre, t_1NetValue);
				dataSource.Add(dataEntry);
			}
			foreach (var netValuePre in netValuePres)
			{
				if (!fundDict.ContainsKey(netValuePre.FundCode))
				{
					CheckedEntry dataEntry = new CheckedEntry(reportDate, null, netValuePre, null);
					dataSource.Add(dataEntry);
				}
			}

			return dataSource;
		}

		public class CheckedEntry
		{
			public CheckedEntry(DateTime reportDate, Fund fund, NetValuePre netValuePre, NetValue previousNetValue)
			{
				if (fund != null)
				{
					FundCode = fund.Code;
					FundName = fund.Name;
					Duration = (reportDate - fund.Established.Value).Days;
				}
				if (netValuePre != null)
				{
					UnitNetValue = netValuePre.UnitNetValue;
					AccumulatedNetValue = netValuePre.AccumulatedNetValue;
					UnitNetValue1 = netValuePre.UnitNetValue1;
					AccumulatedNetValue1 = netValuePre.AccumulatedNetValue1;
					UnitNetValue2 = netValuePre.UnitNetValue2;
					AccumulatedNetValue2 = netValuePre.AccumulatedNetValue2;
					UnitNetValue3 = netValuePre.UnitNetValue3;
					AccumulatedNetValue3 = netValuePre.AccumulatedNetValue3;
				}
				if (previousNetValue != null)
				{
					PreviousUnitNetValue = previousNetValue.UnitNetValue;
					PreviousAccumulatedNetValue = previousNetValue.AccumulatedNetValue;

					if (UnitNetValue.HasValue && AccumulatedNetValue.HasValue)
					{
						UnitNetValueGrowthValue = UnitNetValue.Value - PreviousUnitNetValue;
						AccumulatedNetValueGrowthValue = AccumulatedNetValue.Value - PreviousAccumulatedNetValue;
					}
				}
			}

			public string FundCode { get; set; }
			public string FundName { get; set; }
			public decimal? UnitNetValue { get; set; }
			public decimal? AccumulatedNetValue { get; set; }
			public decimal? UnitNetValue1 { get; set; }
			public decimal? AccumulatedNetValue1 { get; set; }
			public decimal? UnitNetValue2 { get; set; }
			public decimal? AccumulatedNetValue2 { get; set; }
			public decimal? UnitNetValue3 { get; set; }
			public decimal? AccumulatedNetValue3 { get; set; }
			public DateTime ReportDate { get; set; }
			public int Duration { get; set; }

			public decimal PreviousUnitNetValue { get; set; }
			public decimal PreviousAccumulatedNetValue { get; set; }

			public decimal UnitNetValueGrowthValue { get; set; }
			public decimal AccumulatedNetValueGrowthValue { get; set; }
		}
	}
}